﻿using JewererBasic.Classes;
using JewererBasic.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Transactions;
using System.Web;

namespace JewererBasic.BO
{   
    public class MCBagBO
    {
        MSQDBEntities db = new MSQDBEntities();

        public BAG_PROCESS GetCurrentProcess(BAG bag)
        {
            foreach (var item in bag.BAG_PROCESS)
            {
                if (item.Finish == 0)
                    return item;
            }
            return null;
        }

        public BAG_PROCESS_HISTORY GetCurrentProcessHistory(BAG bag)
        {
            foreach (var item in bag.BAG_PROCESS_HISTORY)
            {
                if (item.Status == 0)
                    return item;
            }
            return null;
        }

        public bool Update(NewMCViewModel model)
        {
            using (TransactionScope scope=new TransactionScope())
            {
                string bagId = model.Bag.Id;
                double bag_weight = -1;

                if (model.Current_Bag_Process != null)
                {
                    // Finish current process
                    BAG_PROCESS bp = db.BAG_PROCESS.Find(bagId, model.Current_Bag_Process.IdProcess);
                    if (bp != null)
                    {
                        if (bp.WeightIn != null)
                        {
                            bp.WeightOut = Math.Round(model.Current_Bag_Process.WeightOut.Value, 3);
                            bag_weight = Math.Round(bp.WeightOut.Value, 3);// to caculate current_weight of bag
                            if (model.Current_Bag_Process.RejectWeight != null)
                            {
                                bp.RejectWeight = Math.Round(model.Current_Bag_Process.RejectWeight.Value, 3);

                                // Tra lai kho
                                COMPONENT component = bp.BAG.BAG_COMPONENT.First().COMPONENT;
                                if (component != null)
                                {
                                    component.Weight = Math.Round(bp.RejectWeight.Value + component.Weight.Value, 3);

                                    COMPONENT_EXPORTBAG export = new COMPONENT_EXPORTBAG();
                                    export.DayMake = DateTime.Now;
                                    export.IdBag = bp.IdBag;
                                    export.IdReceiver = bp.WorkerId.Value;
                                    export.IdCreater = CurrentUser.UserID;
                                    db.COMPONENT_EXPORTBAG.Add(export);
                                    db.SaveChanges();
                                    COMPONENT_EXPORTBAGDETAIL export_detail = new COMPONENT_EXPORTBAGDETAIL();
                                    export_detail.IdComponent = component.Id;
                                    export_detail.IdExport = export.IdExport;
                                    export_detail.Reason = "Reject weight from bag" + bp.IdBag + " in process: " + bp.PROCESS.Name;
                                    export_detail.Weight = Math.Round(bp.RejectWeight.Value, 3);
                                    db.COMPONENT_EXPORTBAGDETAIL.Add(export_detail);
                                    db.SaveChanges();
                                    // Test ki cho nay
                                }
                            }
                        }
                        bp.DateOut = DateTime.Now;
                        bp.Finish = 1;
                        db.SaveChanges();
                    }
                    // Finish current process history
                    BAG_PROCESS_HISTORY bh = db.BAG_PROCESS_HISTORY.Find(model.Current_Bag_Process_History.Id);
                    if (bh != null)
                    {
                        if (bh.WeigthIn != null)
                        {
                            bh.WeightOut = Math.Round(model.Current_Bag_Process.WeightOut.Value, 3);
                            if (model.Current_Bag_Process.RejectWeight != null)
                            {
                                bh.RejectWeight = Math.Round(model.Current_Bag_Process.RejectWeight.Value, 3);

                            }

                            // Update data in waste_worker
                            Waste_Report_BO.Update_Worker_Waste(bh.WorkerId.Value, bh);

                        }
                        bh.DateOut = DateTime.Now;
                        bh.Status = 1;
                        db.SaveChanges();
                    }
                }

                #region Start
                // Start next process
                if (model.Next_Bag_Process != null)
                {
                    BAG_PROCESS nBP = db.BAG_PROCESS.Find(bagId, model.Next_Bag_Process.IdProcess);
                    if (nBP != null)
                    {
                        // check if rework, clear current information
                        if (nBP.DateOut != null)
                        {
                            nBP.DateOut = null;
                            nBP.WeightOut = null;
                            nBP.RejectWeight = null;
                            nBP.WorkerId = null;
                        }
                        nBP.Finish = 0;
                        nBP.DateIn = DateTime.Now;
                        nBP.MC = model.Next_Bag_Process.MC;

                        if (model.Next_Bag_Process.WeightIn != null)// not waiting
                        {
                            nBP.WeightIn = Math.Round(model.Next_Bag_Process.WeightIn.Value, 3);
                            nBP.WorkerId = model.Next_Bag_Process.WorkerId;
                            bag_weight = Math.Round(nBP.WeightIn.Value, 3);
                        }

                        db.SaveChanges();

                        // Add more bag process history
                        BAG_PROCESS_HISTORY nBH = model.Next_Bag_Process_History;
                        nBH.IdBag = bagId;
                        nBH.DateIn = DateTime.Now;
                        nBH.IdProcess = model.Next_Bag_Process.IdProcess;
                        nBH.MC = model.Next_Bag_Process.MC;
                        nBH.Status = 0;

                        if (model.Next_Bag_Process.WeightIn != null) // not waiting
                        {
                            nBH.WeigthIn = Math.Round(model.Next_Bag_Process.WeightIn.Value, 3);
                            nBH.WorkerId = model.Next_Bag_Process.WorkerId;
                        }

                        db.BAG_PROCESS_HISTORY.Add(nBH);
                        db.SaveChanges();

                    }
                }
                #endregion

                if (bag_weight != -1)
                {
                    BAG bag = db.BAGs.Find(bagId);
                    bag.Current_Weight = bag_weight;
                    db.SaveChanges();
                }
                scope.Complete();
                return true;
            }
        }

        public void StartBag(string bagId)
        {
            BAG bag = db.BAGs.Find(bagId);
            if (bag != null)
            {
                bag.Finish = 0;
                db.SaveChanges();
            }
        }

        public void FinishBag(NewMCViewModel model)
        {
            BAG bag = db.BAGs.Find(model.Bag.Id);            
            if (bag != null)
            {
                double bag_weight = -1; 
                BAG_PROCESS bp = this.GetCurrentProcess(bag);
                if (bp != null)
                {
                    bp.DateOut = DateTime.Now;
                    if (bp.WeightIn != null)
                    {
                        bp.WeightOut = Math.Round(model.Current_Bag_Process.WeightOut.Value, 3);
                        bag_weight = Math.Round(bp.WeightOut.Value, 3);
                        if (model.Current_Bag_Process.RejectWeight != null)
                        {
                            // tra lai kho
                            COMPONENT component = bp.BAG.BAG_COMPONENT.First().COMPONENT;
                            if (component != null)
                            {
                                component.Weight = Math.Round(model.Current_Bag_Process.RejectWeight.Value + component.Weight.Value, 3);

                                COMPONENT_EXPORTBAG export = new COMPONENT_EXPORTBAG();
                                export.DayMake = DateTime.Now;
                                export.IdBag = bp.IdBag;
                                export.IdReceiver = bp.WorkerId.Value;
                                export.IdCreater = CurrentUser.UserID;
                                db.COMPONENT_EXPORTBAG.Add(export);
                                db.SaveChanges();
                                COMPONENT_EXPORTBAGDETAIL export_detail = new COMPONENT_EXPORTBAGDETAIL();
                                export_detail.IdComponent = component.Id;
                                export_detail.IdExport = export.IdExport;
                                export_detail.Reason = "Reject weight from bag" + bp.IdBag + " in process: " + bp.PROCESS.Name;
                                export_detail.Weight = Math.Round(model.Current_Bag_Process.RejectWeight.Value, 3);
                                db.COMPONENT_EXPORTBAGDETAIL.Add(export_detail);
                                db.SaveChanges();
                                // Test ki cho nay
                            }
                            bp.RejectWeight = Math.Round(model.Current_Bag_Process.RejectWeight.Value, 3);
                        }
                    }                    
                    bp.Finish = 1;

                    BAG_PROCESS_HISTORY bh = this.GetCurrentProcessHistory(bag);
                    if (bh != null)
                    {
                        bh.DateOut = DateTime.Now;
                        if (bh.WeigthIn != null)
                        {
                            bh.WeightOut = Math.Round(model.Current_Bag_Process.WeightOut.Value, 3);
                            if (model.Current_Bag_Process.RejectWeight != null)
                                bh.RejectWeight = Math.Round(model.Current_Bag_Process.RejectWeight.Value, 3);
                            Waste_Report_BO.Update_Worker_Waste(bh.WorkerId.Value, bh);
                        }                       
                        bh.Status = 1;
                    }
                }
                bag.Finish = 1;
                if (bag_weight != -1)
                    bag.Current_Weight = bag_weight;
                db.SaveChanges();
            }
        }

        public BAG FindBag(string bagId)
        {
            return db.BAGs.Find(bagId);
        }

        public bool IsRework(int processId, string bagId)
        {
            var query = db.BAG_PROCESS.Find(bagId, processId);
            if (query != null)
            {
                if (query.DateOut != null)
                    return true;
            }
            return false;
        }

        public bool CheckIfWaitingProcess(int processId)
        {
            PROCESS process = db.PROCESSes.Find(processId);
            if (process == null)
                return false;
            if (process.Name.IndexOf("Waiting") >= 0)
                return true;
            return false;
        }

        public void Restart(string p)
        {
            BAG bag = db.BAGs.Find(p);
            if (bag != null)
            {
                if (bag.Finish == 1)
                {
                    bag.Finish = 0;
                    db.SaveChanges();
                }
            }
        }

        public static int GetCurrentProcessId(string bagId)
        {
            MSQDBEntities db = new MSQDBEntities();
            BAG bag = db.BAGs.Find(bagId);
            if (bag != null)
            {
                foreach (var item in bag.BAG_PROCESS_HISTORY)
                {
                    if (item.Status == 0)
                        return item.IdProcess;
                }
            }
            return -1;
        }
    }
}